require 'fileutils'
require 'kconv'

class CacheManager

  def initialize(base_dir=nil)
    @base_dir=base_dir
    init_dir
  end

  def get(lyric)
    file=lyric2file(lyric)
    if !File.exists?(file) && !@alt_dir.nil?
      file=lyric2file(lyric,@alt_dir)
    end 
    return false unless File.exists?(file)
    read_lyric_file(file,lyric)
  end

  def store(lyric)
    file=lyric2file(lyric)
    file_dir=File.dirname(file)
    FileUtils.mkdir_p(file_dir) unless File.exists?(file_dir) 
    
    File.open(file,'w') do |f|
      f << "#{lyric.artist} - #{lyric.title}\n\n".toutf8
      f << lyric.text.toutf8
    end
  end

  def get_lyrics
    res=[]
    Dir.foreach(@base_dir) do |artist_dir|
      artist_dir_path=File.join(@base_dir,artist_dir)
      if File.directory?(artist_dir_path)
        Dir.foreach(artist_dir_path) do |lyric_file|
          ext=File.extname(lyric_file)
          if ext==".lyric"
            basename=File.basename(lyric_file,ext)
            lyric_file_path=File.join(artist_dir_path,lyric_file)
            lyric=Lyric.new({:artist=>artist_dir, :title=>basename})
            read_lyric_file(lyric_file_path,lyric)
            res << lyric
          end
        end
      end
    end
    res
  end
    
  def get_album(album)
    file=lyric2file(album,@album_dir,'.album')
    return false unless File.exists?(file)
    text=IO.read(file)
    Album.load(text)
  end
  
  def get_albums
    res=[]
    Dir.foreach(@album_dir) do |artist_dir|
      artist_dir_path=File.join(@album_dir,artist_dir)
      if File.directory?(artist_dir_path)
        Dir.foreach(artist_dir_path) do |album_file|
          ext=File.extname(album_file)
          if ext==".album"
            basename=File.basename(album_file,ext)
            album_file_path=File.join(artist_dir_path,album_file)
            text=IO.read(album_file_path)
            res << Album.load(text)
          end
        end
      end
    end
    res
  end
  
  def store_album(album)
    file=lyric2file(album,@album_dir,'.album')
    file_dir=File.dirname(file)
    FileUtils.mkdir_p(file_dir) unless File.exists?(file_dir) 
    File.open(file,'w') do |f|
      f << album.save
    end
    
    
  end


  private

  def lyric2file(lyric,dir=@base_dir,ext='.lyric')
    title=fix_string(lyric.title)
    artist=fix_string(lyric.artist)
    artist_dir=File.join(dir,artist)
    song_file=File.join(dir,artist,title+ext)
    song_file
  end
  
  def fix_string string
    @re_inv_chars=/[\x00\/\\:\*\?\"<>\|]/ unless @re_inv_chars
    string.strip.downcase.gsub(@re_inv_chars,'_')
  end

  def read_lyric_file(file, lyric=Lyric.new)
    s=[]
    IO.foreach(file) do |line|
      s << line
    end
    lyric.artist,lyric.title=s.shift.split(" - ").collect!{|el| el.strip}
    s.shift if s[0]=="\n"
    lyric.text=s
  end
  
  def init_dir
    lyric_home=File.join(ENV['HOME'],'Lyrics')
    lyric_ebook_home=File.join(ENV['HOME'],'.lyrics_ebook','Lyrics')
    lyric_home_exists=File.exists?(lyric_home) && File.directory?(lyric_home)
    @base_dir=lyric_home_exists ? lyric_home : lyric_ebook_home if @base_dir.nil?
    @alt_dir=lyric_home_exists ? lyric_ebook_home : nil
    @album_dir=File.join(ENV['HOME'],'.lyrics_ebook','Albums')
    FileUtils.mkdir_p(@album_dir) unless File.exists?(@album_dir)
  end


end
